Hirschberg proposed one quadratic space and two linear space algorithms for the longest common subsequence(LCS) of two strings. This algorithm(Algorithm C) is a devide and conquer approch. The idea is to find the intersecting point of the LCS sequence with the m/2 th row and solve the problem recursively. This algorithm solves LCS problem in O(mn) time and in O(m+n) space.
int Hirschberg_AlgC(char *stringA, char *stringB, int m, int n) { int **arr, **arr2, i, j, max, arrmax, arr2max, up, down; if (m == 1 || n == 0){ if (n == 0) return 0; for (j = 1; j <= n; j++){ if (stringA[1] == stringB[j]) return 1; } return 0; } arr = (int**)calloc(2, sizeof(int*)); arr2 = (int**)calloc(2, sizeof(int*)); arrmax = m / 2; arr2max = m - arrmax; up = 1; down = 0; for (i = 0; i < 2; i++){ arr[i] = (int*)calloc((n + 1), sizeof(int)); arr2[i] = (int*)calloc((n + 1), sizeof(int)); } /*-----fill in arr by using algB -----*/ for (i = 0; i <= arrmax; i++){ for (j = 0; j <= n; j++){ if (j == 0 || i == 0) arr[down][j] = 0; else{ if (stringA[i] == stringB[j]){ arr[down][j] = arr[up][j - 1] + 1; } else{ arr[down][j] = arr[up][j]; if (arr[down][j] < arr[down][j - 1]) arr[down][j] = arr[down][j - 1]; } } } up ^= down;//swap up and down by using EXOR down ^= up; up ^= down; } arrmax = up;//remember the position of the last row /*-----fill in arr2 by using algB -----*/ for (i = 0; i <= arr2max; i++){ for (j = 0; j <= n; j++){ if (j == 0 || i == 0) arr2[down][j] = 0; else{ if (stringA[m - i + 1] == stringB[n - j + 1]){ arr2[down][j] = arr2[up][j - 1] + 1; } else{ arr2[down][j] = arr2[up][j]; if (arr2[down][j] < arr2[down][j - 1]) arr2[down][j] = arr2[down][j - 1]; } } } up ^= down;//swap up and down by using EXOR down ^= up; up ^= down; } arr2max = up;//remember the position of the last row /*-----find k and MAX-----*/ max = 0; j = 0;//the k is the min j that makes MAX for (i = 0; i <= n; i++){ if (arr[arrmax][i] + arr2[arr2max][n - i] > max){ max = arr[arrmax][i] + arr2[arr2max][n - i]; j = i; } } return Hirschberg_AlgC(stringA, stringB, m / 2, j) + Hirschberg_AlgC(&stringA[m / 2], &stringB[j], m - m / 2, n - j); }